with Ada.Strings.Wide_Fixed; use Ada.Strings.Wide_Fixed;
with Ada.Strings.Wide_Maps;  use Ada.Strings.Wide_Maps;
with Ada.Strings.Wide_Maps.Wide_Constants;

package body keyword_parser is
  function parse_line(words : in wide_string;
                      on : in wide_string) return boolean is
    separator : constant wide_character := ';';

    k : integer;
    function enumerate_words (from : wide_string) return integer is
      i, n: integer;
    begin
      i := from'first; n := 0;
      while i < from'last loop
        while from(i) = separator and i < from'last loop
          i := i+1;
        end loop;
        if from(i) /= separator then n := n+1; end if;
        while from(i) /= separator and i < from'last loop
          i := i+1;
        end loop;
      end loop;
      return n;
    end enumerate_words;

    function get_word (word : integer; from : wide_string) return wide_string is
      n, i, j : integer;
      procedure skip_words is
      begin
        n := 0; j := from'first;
        while j < from'last and n < word loop
          while from(j) = separator and j < from'last loop
            j := j+1;
          end loop;
          while from(j) /= separator and j < from'last loop
            j := j+1;
          end loop;
          if from(j) = separator and j< from'last then n:= n+1; end if;
          j := j+1;
        end loop;
      end skip_words;
      procedure get_word_start is
      begin
        i := from'first;
        while from(j-i) = separator and j-i > from'first loop
          j := j-1;
        end loop;
        while from(j-i) /= separator and j-i > from'first loop
          i:= i+1;
        end loop;
        if from(j-i) = separator then i:= i-1; end if;
      end get_word_start;
    begin
      skip_words;
      get_word_start;
      return from(j-i..j-1);
    end get_word;

    str : constant wide_string := Translate(on, Wide_Constants.Lower_Case_Map);
  begin
    for i in 1..Enumerate_words(words) loop
      declare
        word : constant wide_string := Get_Word(i, words);
      begin
        k := 1;
        if word'length <= str'length then
          while k <= on'Length-word'length
            and Translate(word, Wide_Constants.Lower_Case_Map) /= str(k..k+word'length-1)
          and word'length <= str'length
          loop
            k := k+1;
          end loop;
          if Translate(word, Wide_Constants.Lower_Case_Map) = str(k..k+word'length-1) then
            return True;
          end if;
        end if;
      end;
    end loop;
    return False;
  exception
    when Constraint_Error => return False;
  end parse_line;
end keyword_parser;
